
// this is autogenerated file, do not edit it.
#include "ficus/ficus.h"


#include <string.h>

typedef struct _fx_LS_data_t {
   int_ rc;
   struct _fx_LS_data_t* tl;
   fx_str_t hd;
} _fx_LS_data_t, *_fx_LS;

typedef struct _fx_Nt6option1i {
   int tag;
   union {
      int_ Some;
   } u;
} _fx_Nt6option1i;

typedef struct _fx_T3LSiB {
   struct _fx_LS_data_t* t0;
   int_ t1;
   bool t2;
} _fx_T3LSiB;

typedef struct _fx_T2LSi {
   struct _fx_LS_data_t* t0;
   int_ t1;
} _fx_T2LSi;

typedef struct _fx_T2SB {
   fx_str_t t0;
   bool t1;
} _fx_T2SB;

typedef struct {
   int_ rc;
   int_ data;
} _fx_E4Exit_data_t;

typedef struct {
   int_ rc;
   fx_str_t data;
} _fx_E4Fail_data_t;

static void _fx_free_LS(struct _fx_LS_data_t** dst)
{
   FX_FREE_LIST_IMPL(_fx_LS, fx_free_str);
}

static int _fx_cons_LS(fx_str_t* hd, struct _fx_LS_data_t* tl, bool addref_tl, struct _fx_LS_data_t** fx_result)
{
   FX_MAKE_LIST_IMPL(_fx_LS, fx_copy_str);
}

static void _fx_free_T3LSiB(struct _fx_T3LSiB* dst)
{
   _fx_free_LS(&dst->t0);
}

static void _fx_copy_T3LSiB(struct _fx_T3LSiB* src, struct _fx_T3LSiB* dst)
{
   FX_COPY_PTR(src->t0, &dst->t0);
   dst->t1 = src->t1;
   dst->t2 = src->t2;
}

static void _fx_make_T3LSiB(struct _fx_LS_data_t* t0, int_ t1, bool t2, struct _fx_T3LSiB* fx_result)
{
   FX_COPY_PTR(t0, &fx_result->t0);
   fx_result->t1 = t1;
   fx_result->t2 = t2;
}

static void _fx_free_T2LSi(struct _fx_T2LSi* dst)
{
   _fx_free_LS(&dst->t0);
}

static void _fx_copy_T2LSi(struct _fx_T2LSi* src, struct _fx_T2LSi* dst)
{
   FX_COPY_PTR(src->t0, &dst->t0);
   dst->t1 = src->t1;
}

static void _fx_make_T2LSi(struct _fx_LS_data_t* t0, int_ t1, struct _fx_T2LSi* fx_result)
{
   FX_COPY_PTR(t0, &fx_result->t0);
   fx_result->t1 = t1;
}

static void _fx_free_T2SB(struct _fx_T2SB* dst)
{
   fx_free_str(&dst->t0);
}

static void _fx_copy_T2SB(struct _fx_T2SB* src, struct _fx_T2SB* dst)
{
   fx_copy_str(&src->t0, &dst->t0);
   dst->t1 = src->t1;
}

static void _fx_make_T2SB(fx_str_t* t0, bool t1, struct _fx_T2SB* fx_result)
{
   fx_copy_str(t0, &fx_result->t0);
   fx_result->t1 = t1;
}

FX_EXTERN_C int _fx_F3ordi1C(char_ c_0, int_* fx_result, void* fx_fv);

FX_EXTERN_C int _fx_F4joinS2SLS(fx_str_t* sep_0, struct _fx_LS_data_t* strs_0, fx_str_t* fx_result, void* fx_fv);

FX_EXTERN_C int _fx_M6StringFM4copyS1S(fx_str_t* s, fx_str_t* fx_result, void* fx_fv)
{
   
return fx_make_str(s->data, s->length, fx_result);

}

FX_EXTERN_C bool _fx_M6StringFM10startswithB2SS(fx_str_t* s, fx_str_t* prefix, void* fx_fv)
{
   
int_ sz1 = s->length;
    int_ sz2 = prefix->length;
    return sz2 == 0 ? true : sz2 <= sz1 && memcmp(s->data, prefix->data,
        (size_t)(sz2*sizeof(s->data[0]))) == 0;

}

FX_EXTERN_C bool _fx_M6StringFM10startswithB2SC(fx_str_t* s, char_ prefix, void* fx_fv)
{
   
return s->length > 0 && s->data[0] == prefix;

}

FX_EXTERN_C bool _fx_M6StringFM8endswithB2SS(fx_str_t* s, fx_str_t* suffix, void* fx_fv)
{
   
int_ sz1 = s->length;
    int_ sz2 = suffix->length;
    return sz2 == 0 ? true : sz2 <= sz1 && memcmp(s->data + (sz1 - sz2), suffix->data,
        (size_t)(sz2*sizeof(s->data[0]))) == 0;

}

FX_EXTERN_C bool _fx_M6StringFM8endswithB2SC(fx_str_t* s, char_ suffix, void* fx_fv)
{
   
return s->length > 0 && s->data[s->length-1] == suffix;

}

FX_EXTERN_C int_ _fx_M6StringFM4findi3SSi(fx_str_t* s, fx_str_t* part, int_ from_pos, void* fx_fv)
{
   
int_ i, sz1 = s->length, sz2 = part->length, l = sz1 - sz2 + 1;
    if (sz2 == 0)
        return 0;
    for( i = (from_pos >= 0 ? from_pos : 0); i < l; i++ ) {
        if( s->data[i] == part->data[0] &&
            memcmp(s->data + i, part->data, sz2*sizeof(part->data[0])) == 0 )
            return i;
    }
    return -1;

}

FX_EXTERN_C int_ _fx_M6StringFM4findi2SC(fx_str_t* s, char_ c, void* fx_fv)
{
   
int_ i, sz1 = s->length;
    for( i = 0; i < sz1; i++ )
        if( s->data[i] == c ) return i;
    return -1;

}

FX_EXTERN_C int_ _fx_M6StringFM5rfindi3SSi(fx_str_t* s, fx_str_t* part, int_ from_pos, void* fx_fv)
{
   
int_ sz1 = s->length, sz2 = part->length;
    int_ i = (from_pos < sz1 ? from_pos+1 : sz1) - sz2;
    if (sz2 == 0)
        return i - 1;
    for ( ; i >= 0; i--) {
        if( memcmp(s->data + i, part->data, sz2*sizeof(part->data[0])) == 0)
            break;
    }
    return i;

}

FX_EXTERN_C int_ _fx_M6StringFM5rfindi2SC(fx_str_t* s, char_ c, void* fx_fv)
{
   
int_ i, sz1 = s->length;
    for( i = sz1-1; i >= 0; i-- )
        if( s->data[i] == c ) return i;
    return -1;

}

FX_EXTERN_C int_ _fx_M6StringFM5rfindi3SCi(fx_str_t* s, char_ c, int_ from_pos, void* fx_fv)
{
   
int_ i, sz1 = s->length;
    for( i = (from_pos < sz1 ? from_pos : sz1-1); i >= 0; i-- )
        if( s->data[i] == c ) return i;
    return -1;

}

FX_EXTERN_C bool _fx_M6StringFM8containsB2SC(fx_str_t* s, char_ c, void* fx_fv)
{
   
int_ i, sz = s->length;
    char_* data = s->data;

    for ( i = 0; i < sz; i++ ) {
        if (data[i] == c) return true;
    }
    return false;

}

FX_EXTERN_C int _fx_M6StringFM7replaceS3SSS(
   fx_str_t* s,
   fx_str_t* substr,
   fx_str_t* new_substr,
   fx_str_t* fx_result,
   void* fx_fv)
{
   
int_ i, j = 0, sz = s->length, sz1 = substr->length, sz2 = new_substr->length;
    int_ newsz = 0;
    if (sz == 0 || sz1 == 0) {
        fx_copy_str(s, fx_result);
        return FX_OK;
    }
    for( i = 0; i < sz; ) {
        if( i <= sz - sz1 && s->data[i] == substr->data[0] &&
            memcmp(s->data + i, substr->data, sz1*sizeof(s->data[0])) == 0 ) {
            newsz += sz2;
            i += sz1;
        } else {
            newsz++;
            i++;
        }
    }
    int fx_status = fx_make_str(0, newsz, fx_result);
    if (fx_status >= 0) {
        for( i = 0; i < sz; ) {
            if( i <= sz - sz1 && s->data[i] == substr->data[0] &&
                memcmp(s->data + i, substr->data, sz1*sizeof(s->data[0])) == 0 ) {
                if (sz2 > 0)
                    memcpy(fx_result->data + j, new_substr->data, sz2*sizeof(s->data[0]));
                j += sz2;
                i += sz1;
            } else {
                fx_result->data[j++] = s->data[i++];
            }
        }
    }
    return fx_status;

}

FX_EXTERN_C int _fx_M6StringFM12decapitalizeS1S(fx_str_t* s, fx_str_t* fx_result, void* fx_fv)
{
   
int_ sz = s->length;
    const char_* src = s->data;
    if (sz == 0 || fx_tolower(src[0]) == src[0]) {
        fx_copy_str(s, fx_result);
        return FX_OK;
    }
    int fx_status = fx_make_str(0, sz, fx_result);
    if( fx_status >= 0 ) {
        char_* dst = fx_result->data;
        dst[0] = fx_tolower(src[0]);
        for (int_ i = 1; i < sz; i++)
            dst[i] = src[i];
    }
    return fx_status;

}

FX_EXTERN_C int _fx_M6StringFM6rstripS1S(fx_str_t* s, fx_str_t* fx_result, void* fx_fv)
{
   
const char_* ptr = s->data;
    int_ sz = s->length;
    for (; sz > 0 && fx_isspace(ptr[sz - 1]); sz--)
        ;
    return fx_substr(s, 0, sz, 1, 0, fx_result);

}

FX_EXTERN_C int _fx_M6StringFM5stripS1S(fx_str_t* s, fx_str_t* fx_result, void* fx_fv)
{
   
const char_* ptr = s->data;
    int_ i = 0, sz = s->length;
    for (; i < sz && fx_isspace(ptr[i]); i++)
        ;
    for (; sz > i && fx_isspace(ptr[sz - 1]); sz--)
        ;
    return fx_substr(s, i, sz, 1, 0, fx_result);

}

FX_EXTERN_C int _fx_M6StringFM5splitLS3SCB(
   fx_str_t* s_0,
   char_ c_0,
   bool allow_empty_0,
   struct _fx_LS_data_t** fx_result,
   void* fx_fv)
{
   _fx_T3LSiB __fold_result___0 = {0};
   fx_str_t s_1 = {0};
   _fx_T3LSiB v_0 = {0};
   _fx_LS sl_0 = 0;
   _fx_LS v_1 = 0;
   fx_str_t v_2 = {0};
   _fx_LS __fold_result___1 = 0;
   int fx_status = 0;
   _fx_make_T3LSiB(0, 0, true, &__fold_result___0);
   fx_copy_str(s_0, &s_1);
   int_ len_0 = FX_STR_LENGTH(s_1);
   for (int_ i_0 = 0; i_0 < len_0; i_0++) {
      _fx_T3LSiB v_3 = {0};
      _fx_LS sl_1 = 0;
      _fx_T3LSiB v_4 = {0};
      _fx_LS v_5 = 0;
      fx_str_t v_6 = {0};
      char_ ci_0 = s_1.data[i_0];
      _fx_copy_T3LSiB(&__fold_result___0, &v_3);
      FX_COPY_PTR(v_3.t0, &sl_1);
      int_ start_0 = v_3.t1;
      bool sep_0 = v_3.t2;
      if (ci_0 == c_0) {
         bool t_0;
         if (sep_0) {
            t_0 = !allow_empty_0;
         }
         else {
            t_0 = false;
         }
         if (t_0) {
            FX_COPY_PTR(sl_1, &v_5);
         }
         else {
            FX_CALL(fx_substr(s_0, start_0, i_0, 1, 0, &v_6), _fx_catch_0);
            FX_CALL(_fx_cons_LS(&v_6, sl_1, true, &v_5), _fx_catch_0);
         }
         _fx_make_T3LSiB(v_5, i_0 + 1, true, &v_4);
      }
      else {
         int_ t_1;
         if (sep_0) {
            t_1 = i_0;
         }
         else {
            t_1 = start_0;
         }
         _fx_make_T3LSiB(sl_1, t_1, false, &v_4);
      }
      _fx_free_T3LSiB(&__fold_result___0);
      _fx_copy_T3LSiB(&v_4, &__fold_result___0);

   _fx_catch_0: ;
      FX_FREE_STR(&v_6);
      if (v_5) {
         _fx_free_LS(&v_5);
      }
      _fx_free_T3LSiB(&v_4);
      if (sl_1) {
         _fx_free_LS(&sl_1);
      }
      _fx_free_T3LSiB(&v_3);
      FX_CHECK_EXN(_fx_cleanup);
   }
   _fx_copy_T3LSiB(&__fold_result___0, &v_0);
   FX_COPY_PTR(v_0.t0, &sl_0);
   int_ start_1 = v_0.t1;
   bool sep_1 = v_0.t2;
   if (sep_1) {
      FX_COPY_PTR(sl_0, &v_1);
   }
   else {
      FX_CALL(fx_substr(s_0, start_1, 0, 1, 2, &v_2), _fx_cleanup); FX_CALL(_fx_cons_LS(&v_2, sl_0, true, &v_1), _fx_cleanup);
   }
   _fx_LS lst_0 = v_1;
   for (; lst_0; lst_0 = lst_0->tl) {
      _fx_LS r_0 = 0;
      fx_str_t* a_0 = &lst_0->hd;
      FX_COPY_PTR(__fold_result___1, &r_0);
      FX_CALL(_fx_cons_LS(a_0, r_0, false, &r_0), _fx_catch_1);
      _fx_free_LS(&__fold_result___1);
      FX_COPY_PTR(r_0, &__fold_result___1);

   _fx_catch_1: ;
      if (r_0) {
         _fx_free_LS(&r_0);
      }
      FX_CHECK_EXN(_fx_cleanup);
   }
   FX_COPY_PTR(__fold_result___1, fx_result);

_fx_cleanup: ;
   _fx_free_T3LSiB(&__fold_result___0);
   FX_FREE_STR(&s_1);
   _fx_free_T3LSiB(&v_0);
   if (sl_0) {
      _fx_free_LS(&sl_0);
   }
   if (v_1) {
      _fx_free_LS(&v_1);
   }
   FX_FREE_STR(&v_2);
   if (__fold_result___1) {
      _fx_free_LS(&__fold_result___1);
   }
   return fx_status;
}

FX_EXTERN_C void _fx_M6StringFM7to_int_Nt6option1i2Si(fx_str_t* a, int_ base, struct _fx_Nt6option1i* fx_result, void* fx_fv)
{
   
bool ok = fx_atoi(a, &fx_result->u.Some, (int)base);
    fx_result->tag = (int)(ok+1);

}

FX_EXTERN_C int_ _fx_M6StringFM10to_int_or_i3Sii(fx_str_t* a, int_ defval, int_ base, void* fx_fv)
{
   
int_ result;
    bool ok = fx_atoi(a, &result, (int)base);
    return ok ? result : defval;

}

FX_EXTERN_C int _fx_M6StringFM10num_suffixS1i(int_ n_0, fx_str_t* fx_result, void* fx_fv)
{
   int fx_status = 0;
   int_ v_0 = n_0 % 10;
   if (v_0 == 1) {
      fx_str_t slit_0 = FX_MAKE_STR("st"); fx_copy_str(&slit_0, fx_result);
   }
   else if (v_0 == 2) {
      fx_str_t slit_1 = FX_MAKE_STR("nd"); fx_copy_str(&slit_1, fx_result);
   }
   else if (v_0 == 3) {
      fx_str_t slit_2 = FX_MAKE_STR("rd"); fx_copy_str(&slit_2, fx_result);
   }
   else {
      fx_str_t slit_3 = FX_MAKE_STR("th"); fx_copy_str(&slit_3, fx_result);
   }
   return fx_status;
}

FX_EXTERN_C int _fx_M6StringFM7escapedS2SB(fx_str_t* s_0, bool quotes_0, fx_str_t* fx_result, void* fx_fv)
{
   fx_str_t q_0 = {0};
   _fx_LS v_0 = 0;
   _fx_T2LSi __fold_result___0 = {0};
   fx_str_t s_1 = {0};
   _fx_T2LSi v_1 = {0};
   _fx_LS ll_0 = 0;
   fx_str_t v_2 = {0};
   _fx_LS v_3 = 0;
   _fx_LS __fold_result___1 = 0;
   _fx_LS v_4 = 0;
   int fx_status = 0;
   if (quotes_0) {
      fx_str_t slit_0 = FX_MAKE_STR("\""); fx_copy_str(&slit_0, &q_0);
   }
   else {
      fx_str_t slit_1 = FX_MAKE_STR(""); fx_copy_str(&slit_1, &q_0);
   }
   FX_CALL(_fx_cons_LS(&q_0, 0, true, &v_0), _fx_cleanup);
   _fx_make_T2LSi(v_0, 0, &__fold_result___0);
   fx_copy_str(s_0, &s_1);
   int_ len_0 = FX_STR_LENGTH(s_1);
   for (int_ i_0 = 0; i_0 < len_0; i_0++) {
      _fx_T2LSi v_5 = {0};
      _fx_LS ll_1 = 0;
      _fx_T2LSi v_6 = {0};
      _fx_T2SB v_7 = {0};
      fx_str_t esc_s_0 = {0};
      _fx_LS v_8 = 0;
      fx_str_t v_9 = {0};
      _fx_LS ll_2 = 0;
      char_ c_0 = s_1.data[i_0];
      _fx_copy_T2LSi(&__fold_result___0, &v_5);
      FX_COPY_PTR(v_5.t0, &ll_1);
      int_ verb_0 = v_5.t1;
      int_ code_0;
      FX_CALL(_fx_F3ordi1C(c_0, &code_0, 0), _fx_catch_0);
      bool t_0;
      if (code_0 >= 40) {
         t_0 = code_0 != 92;
      }
      else {
         t_0 = false;
      }
      if (t_0) {
         _fx_make_T2LSi(ll_1, verb_0, &v_6);
      }
      else {
         if (code_0 == 10) {
            fx_str_t slit_2 = FX_MAKE_STR("\\n"); _fx_make_T2SB(&slit_2, true, &v_7);
         }
         else if (code_0 == 13) {
            fx_str_t slit_3 = FX_MAKE_STR("\\r"); _fx_make_T2SB(&slit_3, true, &v_7);
         }
         else if (code_0 == 9) {
            fx_str_t slit_4 = FX_MAKE_STR("\\t"); _fx_make_T2SB(&slit_4, true, &v_7);
         }
         else if (code_0 == 39) {
            fx_str_t slit_5 = FX_MAKE_STR("\\\'"); _fx_make_T2SB(&slit_5, true, &v_7);
         }
         else if (code_0 == 34) {
            fx_str_t slit_6 = FX_MAKE_STR("\\\""); _fx_make_T2SB(&slit_6, true, &v_7);
         }
         else if (code_0 == 92) {
            fx_str_t slit_7 = FX_MAKE_STR("\\\\"); _fx_make_T2SB(&slit_7, true, &v_7);
         }
         else if (code_0 == 0) {
            fx_str_t slit_8 = FX_MAKE_STR("\\0"); _fx_make_T2SB(&slit_8, true, &v_7);
         }
         else {
            fx_str_t slit_9 = FX_MAKE_STR("\\0"); _fx_make_T2SB(&slit_9, false, &v_7);
         }
         FX_CHECK_EXN(_fx_catch_0);
         fx_copy_str(&v_7.t0, &esc_s_0);
         bool esc_0 = v_7.t1;
         if (esc_0) {
            if (i_0 > verb_0) {
               FX_CALL(fx_substr(s_0, verb_0, i_0, 1, 0, &v_9), _fx_catch_0);
               FX_CALL(_fx_cons_LS(&v_9, ll_1, true, &v_8), _fx_catch_0);
            }
            else {
               FX_COPY_PTR(ll_1, &v_8);
            }
            FX_CALL(_fx_cons_LS(&esc_s_0, v_8, true, &ll_2), _fx_catch_0);
            _fx_make_T2LSi(ll_2, i_0 + 1, &v_6);
         }
         else {
            _fx_make_T2LSi(ll_1, verb_0, &v_6);
         }
      }
      _fx_free_T2LSi(&__fold_result___0);
      _fx_copy_T2LSi(&v_6, &__fold_result___0);

   _fx_catch_0: ;
      if (ll_2) {
         _fx_free_LS(&ll_2);
      }
      FX_FREE_STR(&v_9);
      if (v_8) {
         _fx_free_LS(&v_8);
      }
      FX_FREE_STR(&esc_s_0);
      _fx_free_T2SB(&v_7);
      _fx_free_T2LSi(&v_6);
      if (ll_1) {
         _fx_free_LS(&ll_1);
      }
      _fx_free_T2LSi(&v_5);
      FX_CHECK_EXN(_fx_cleanup);
   }
   _fx_copy_T2LSi(&__fold_result___0, &v_1);
   FX_COPY_PTR(v_1.t0, &ll_0);
   int_ verb_1 = v_1.t1;
   FX_CALL(fx_substr(s_0, verb_1, 0, 1, 2, &v_2), _fx_cleanup);
   FX_CALL(_fx_cons_LS(&v_2, ll_0, true, &v_3), _fx_cleanup);
   FX_CALL(_fx_cons_LS(&q_0, v_3, false, &v_3), _fx_cleanup);
   _fx_LS lst_0 = v_3;
   for (; lst_0; lst_0 = lst_0->tl) {
      _fx_LS r_0 = 0;
      fx_str_t* a_0 = &lst_0->hd;
      FX_COPY_PTR(__fold_result___1, &r_0);
      FX_CALL(_fx_cons_LS(a_0, r_0, false, &r_0), _fx_catch_1);
      _fx_free_LS(&__fold_result___1);
      FX_COPY_PTR(r_0, &__fold_result___1);

   _fx_catch_1: ;
      if (r_0) {
         _fx_free_LS(&r_0);
      }
      FX_CHECK_EXN(_fx_cleanup);
   }
   FX_COPY_PTR(__fold_result___1, &v_4);
   fx_str_t slit_10 = FX_MAKE_STR("");
   FX_CALL(_fx_F4joinS2SLS(&slit_10, v_4, fx_result, 0), _fx_cleanup);

_fx_cleanup: ;
   FX_FREE_STR(&q_0);
   if (v_0) {
      _fx_free_LS(&v_0);
   }
   _fx_free_T2LSi(&__fold_result___0);
   FX_FREE_STR(&s_1);
   _fx_free_T2LSi(&v_1);
   if (ll_0) {
      _fx_free_LS(&ll_0);
   }
   FX_FREE_STR(&v_2);
   if (v_3) {
      _fx_free_LS(&v_3);
   }
   if (__fold_result___1) {
      _fx_free_LS(&__fold_result___1);
   }
   if (v_4) {
      _fx_free_LS(&v_4);
   }
   return fx_status;
}

FX_EXTERN_C int fx_init_String(void)
{
   int fx_status = 0;
   return fx_status;
}

FX_EXTERN_C void fx_deinit_String(void)
{

}

